package nacos_client

import (
	"fmt"
	log "github.com/micro/go-micro/v2/logger"
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/clients/config_client"
	"github.com/nacos-group/nacos-sdk-go/clients/naming_client"
	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"cirrus-core/config/nacos"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
	"web-service/api/config"
)

var nacosClientConfig config_client.IConfigClient

func LoadServiceConfig() error {
	//从nacos-{env}.ini解析配置
	nacosConfig := config.LoadNacosConfig()
	//从nacos配置中心拉取业务配置
	content, err := loadConfigFromNacos(nacosConfig)
	//监听nacos配置中心数据变化
	listenChange(nacosConfig)
	//将nacos拉取的配置写入本地config.ini
	configFile := config.GetConfigFile()
	writeTo(configFile, content)
	//从本地config.ini加载到内存
	config.InitConfig()
	return err
}

func loadConfigFromNacos(nacosConfig *nacos.NacosConfig) (string, error) {
	nacosClientConfig := GetConfigClient(nacosConfig)
	dataId := nacosConfig.DataId
	group := nacosConfig.Group
	content, err := nacosClientConfig.GetConfig(vo.ConfigParam{
		DataId: dataId,
		Group:  group})

	if err != nil {
		log.Errorf("Nacos配置中心连接失败,{env}-nacos.ini配置不正确,"+err.Error()+"!!,NacosAddrs=%s,NameSpaceId=%s,DataId=%s,Group=%s",
			nacosConfig.NacosAddrs,
			nacosConfig.NameSpaceId,
			nacosConfig.DataId,
			nacosConfig.Group,
		)
		os.Exit(0)
		return "", err
	}

	log.Debug("\n", content)
	return content, err
}

func writeTo(filename string, text string) error {
	var content = []byte(text)
	err := ioutil.WriteFile(filename, content, 0666) //写入文件(字节数组)
	return err
}

func listenChange(nacosConfig *nacos.NacosConfig) {
	dataId := nacosConfig.DataId
	group := nacosConfig.Group
	err := nacosClientConfig.ListenConfig(vo.ConfigParam{
		DataId: dataId,
		Group:  group,
		OnChange: func(namespace, group, dataId, data string) {
			log.Info("ListenChange Run")
			fmt.Println("ListenChange Run", data)
			LoadServiceConfig()
		},
	})
	log.Error(err)
}

func NewClientConfig(nacosConfig *nacos.NacosConfig) constant.ClientConfig {
	clientConfig := *constant.NewClientConfig(
		constant.WithNamespaceId(nacosConfig.NameSpaceId), //当namespace是public时，此处填空字符串。
		constant.WithTimeoutMs(5000),
		constant.WithNotLoadCacheAtStart(true),
		//constant.WithLogDir("./nacos/log"),
		//constant.WithCacheDir("./nacos/cache"),
		constant.WithRotateTime("1h"),
		constant.WithMaxAge(3),
		constant.WithLogLevel("debug"),
	)
	return clientConfig
}

func NewServerConfig(nacosConfig *nacos.NacosConfig) []constant.ServerConfig {
	addrs := nacosConfig.NacosAddrs
	arr := strings.Split(addrs, ":")

	if arr[0] == "" {
		log.Error("nacos addr is empty")
	}
	addr := arr[0]
	port := 8848
	if arr[1] != "" {
		intNum, _ := strconv.Atoi(arr[1])
		port = int(uint64(intNum))
	}

	serverConfigs := []constant.ServerConfig{
		*constant.NewServerConfig(
			addr,
			uint64(port),
			constant.WithScheme("http"),
			constant.WithContextPath("/nacos"),
		),
	}
	return serverConfigs
}

func GetNamingConfigClient(nacosConfig *nacos.NacosConfig) naming_client.INamingClient {
	clientConfig := NewClientConfig(nacosConfig)
	serverConfigs := NewServerConfig(nacosConfig)
	namingClient, err := clients.NewNamingClient(
		vo.NacosClientParam{
			ClientConfig:  &clientConfig,
			ServerConfigs: serverConfigs,
		},
	)
	if err != nil {
		log.Error("nacos error", err)
	}
	return namingClient
}

func GetConfigClient(nacosConfig *nacos.NacosConfig) config_client.IConfigClient {
	clientConfig := NewClientConfig(nacosConfig)
	serverConfigs := NewServerConfig(nacosConfig)
	var err error
	nacosClientConfig, err = clients.NewConfigClient(
		vo.NacosClientParam{
			ClientConfig:  &clientConfig,
			ServerConfigs: serverConfigs,
		},
	)
	if err != nil {
		log.Error("nacos error", err)
	}
	return nacosClientConfig
}
